#include <iostream>
#include "contactservice.hpp"
#include "bin_file_oper/file_manager.cc"
using namespace std;

// 根据req的内容完成解析+填充res

void ContactsServer::Add(add_contact_req::AddContactRequest &req, add_contact_res::AddContactResponse *res)
{

    // 打印对应要添加的日志;

    PrintWillAddContactPeople(req);

    // 读取出二进制问价的内容；然后加进去覆盖式添加：

    contacts::Contacts contacts;

    ContactsManager manager;

    manager.ReadContacts(&contacts);

    // 因为请求添加的对应联系人信息和对应的文件中存储的proto格式不一样；进行转换格式：
    contacts::PeopleInfo people;
    BuildPeopleInfo(req, &people);

    // 把对应people添加进去contacts：

    contacts.mutable_contacts()->insert({people.uid(), people});
    manager.InsertContact(contacts);

    res->set_uid(people.uid());
    res->mutable_base_resp()->set_success(true);
    // 打印日志
    cout << "---> AddContact Success to write contacts." << endl;
}

void ContactsServer::Del(del_req::DelContactRequest &req, del_res::DelContactResponse *res)
{
    cout << "--->  DelContactRequest: uid: " << req.uid() << endl;

    contacts::Contacts contacts;

    ContactsManager manager;

    manager.ReadContacts(&contacts);
    // 找不到直接构建错误请求：
    if (contacts.contacts().find(req.uid()) == contacts.contacts().end())
    {

        cout << "--->  not find uid: " << req.uid() << endl;
        res->set_uid(req.uid());
        res->mutable_base_resp()->set_success(false);
        res->mutable_base_resp()->set_error_desc("not find uid");
        return;
    }

    // 能找到直接删除：
    contacts.mutable_contacts()->erase(req.uid());

    // 不要忘了最后结果刷进去文件：

    manager.InsertContact(contacts);
    // 构建答复：

    res->set_uid(req.uid());
    res->mutable_base_resp()->set_success(true);
    // 打印日志
    cout << "---> Success to del contact, uid: " << req.uid() << endl;
}
void ContactsServer::FindOne(find_one_req::FindOneContactRequest &req, find_one_res::FindOneContactResponse *res)
{

    cout << "--->  FindoneContactRequest: uid: " << req.uid() << endl;

    contacts::Contacts contacts;

    ContactsManager manager;

    manager.ReadContacts(&contacts);
    // 找不到直接构建错误请求：
    if (contacts.contacts().find(req.uid()) == contacts.contacts().end())
    {

        cout << "--->  not find uid: " << req.uid() << endl;
        res->set_uid(req.uid());
        res->mutable_base_res()->set_success(false);
        res->mutable_base_res()->set_error_desc("not find uid");
        return;
    }

    contacts::PeopleInfo people = contacts.contacts().find(req.uid())->second;

    BuildFindOneContactResponse(res, people);
    cout << "---> find uid: " << req.uid() << endl;
}
void ContactsServer::FindAll(find_all_contacts_resp::FindAllContactsResponse *res)
{

    cout << "---> findAll " << endl;

    // 获取通讯录
    contacts::Contacts contacts;
    ContactsManager manager;
    manager.ReadContacts(&contacts);

    // 处理转化联系人编号名称信息+转换res消息对象
    BuildFindAllResponse(contacts, res);
}

// 私有成员函数;

void ContactsServer::BuildPeopleInfo(add_contact_req::AddContactRequest req, contacts::PeopleInfo *people)
{
    string uid = Util::GetRandomToHex(10);
    people->set_uid(uid);
    people->set_name(req.name());
    people->set_age(req.age());

    for (auto phone : req.phone())
    {
        contacts::PeopleInfo_Phone *people_phone = people->add_phone();
        people_phone->set_number(phone.number());

        switch (phone.type())
        {

        case add_contact_req::AddContactRequest_Phone_PhoneType_MP:
            people_phone->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
            break;

        case add_contact_req::AddContactRequest_Phone_PhoneType_TEL:
            people_phone->set_type(contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
            break;
        default:
            break;
        }
    }

    // 因为proto对象中的map和c++的map不同不支持拷贝；因此需要遍历填充：
    if (nullptr == people->mutable_remark())
    { // 默认创建的peopleinfo对应map指针不会为空
        std::cout << " addpeople_remark is nullptr!" << std::endl;
        return;
    }
    // 走这
    for (auto it = req.remark().cbegin(); it != req.remark().cend(); ++it)
    {
        people->mutable_remark()->insert({it->first, it->second});
    }
}

void ContactsServer::PrintWillAddContactPeople(add_contact_req::AddContactRequest req)
{
    cout << "---> (ContactsServer::add) AddContactRequest:" << endl;
    cout << "姓名：" << req.name() << endl;
    cout << "年龄：" << req.age() << endl;
    for (auto &phone : req.phone())
    {
        int j = 1;
        cout << "电话" << j++ << ": " << phone.number();
        cout << "  (" << phone.PhoneType_Name(phone.type()) << ")" << endl;
    }
    if (req.remark_size())
    {
        cout << "备注信息: " << endl;
    }
    for (auto it = req.remark().cbegin(); it != req.remark().cend(); ++it)
    {
        cout << "    " << it->first << ": " << it->second << endl;
    }
}

void ContactsServer::BuildFindOneContactResponse(find_one_res::FindOneContactResponse *res, contacts::PeopleInfo people)
{

    if (nullptr == res)
    {
        return;
    }

    
    res->set_uid(people.uid());
    res->set_name(people.name());
    res->set_age(people.age());
    res->mutable_base_res()->set_success(true);
    for (auto phone : people.phone())
    {
        find_one_res::FindOneContactResponse::Phone *people_phone = res->add_phone();
        people_phone->set_number(phone.number());

        switch (phone.type())
        {

        case contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP:
            people_phone->set_type(find_one_res::FindOneContactResponse_Phone_PhoneType_MP);
            break;

        case contacts::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL:
            people_phone->set_type(find_one_res::FindOneContactResponse_Phone_PhoneType_TEL);
            break;
        default:
            break;
        }
    }

    // 因为proto对象中的map和c++的map不同不支持拷贝；因此需要遍历填充：
    if (nullptr == res->mutable_remark())
    {
        std::cout << " addpeople_remark is nullptr!" << std::endl;
        return;
    }
    // 走这
    for (auto it = people.remark().cbegin(); it != people.remark().cend(); ++it)
    {
        res->mutable_remark()->insert({it->first, it->second});
    }
}

void ContactsServer::BuildFindAllResponse(contacts::Contacts &contacts, find_all_contacts_resp::FindAllContactsResponse *res)
{

    if (nullptr == res)
    {
        return;
    }
    res->mutable_base_resp()->set_success(true);
    for (auto it = contacts.contacts().cbegin(); it != contacts.contacts().cend(); ++it)
    {
        find_all_contacts_resp::PeopleInfo *people = res->add_contacts();
        people->set_uid(it->first);
        people->set_name(it->second.name());
    }
}